package zl.osimall.common.service.impl;

import cn.hutool.core.util.IdUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import zl.osimall.common.bean.*;
import zl.osimall.common.exception.SteduException;
import zl.osimall.common.mapper.*;
import zl.osimall.common.service.OrderService;
import zl.osimall.common.utils.MD5Util;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

@Service
public class OrderServiceImpl implements OrderService {
    @Autowired
    private OrderMapper orderMapper;
    @Autowired
    private OrderDetailMapper orderDetailMapper;
    @Autowired
    private CartMapper cartMapper;
    @Autowired
    private AddrMapper addrMapper;
    @Autowired
    private GoodsMapper goodsMapper;
    @Autowired
    private UserMapper userMapper;

    @Transactional(rollbackFor = SteduException.class)
    @Override
    public void add(Order order, Integer[] cartId) throws SteduException {
        String id = IdUtil.getSnowflakeNextIdStr();
        Addr addr = addrMapper.selectById(order.getAddrId());
        if(addr == null || addr.getUserId() != order.getUserId()){
            throw new SteduException("非法收货地址");
        }
        order.setId(id);
        orderMapper.createOrder(order);
        List<Cart> cartList = cartMapper.selectByIds(cartId);
        if(cartId.length != cartList.size()){
            throw new SteduException("非法购物车信息");
        }
        List<OrderDetail> orderDetailList = new ArrayList<>();
        for (Cart cart : cartList){
            if (cart.getUserId() != order.getUserId()){
                throw new SteduException("非法购物车信息");
            }
            if(cart.getGoods().getCount()<cart.getCount()){
                throw new SteduException("库存不足，无法下单");
            }
            if (cart.getGoods().getStatus() == 1){
                throw new SteduException("商品下架，无法下单");
            }
            Goods goods = new Goods();
            goods.setId(cart.getGoods().getId());
            goods.setCount(cart.getGoods().getCount()-cart.getCount());
            goodsMapper.update(goods);
            //BigDecimal price = cart.getGoods().getPrice().multiply(new BigDecimal(cart.getCount()));
            OrderDetail orderDetail = new OrderDetail(null,cart.getCount(),cart.getGoods().getPrice(),cart.getGoodsId(),id,null);
            orderDetailList.add(orderDetail);
        }
        orderDetailMapper.insert(orderDetailList);
        for (Integer cid: cartId){
            cartMapper.delete(cid);
        }

    }

    @Override
    public PageInfo<Order> selectByPage(Order condition ,Integer pageNum , Integer pageSize) {
        PageHelper.startPage(pageNum, pageSize);
        List<Order> orderList = orderMapper.selectByPage(condition);
        return new PageInfo<Order>(orderList);
    }

    @Override
    public List<OrderDetail> selectByOrder(String id) throws SteduException {
        Order order = orderMapper.selectById(id);
        if(order == null){
            throw new SteduException("该订单不存在");
        }
        return orderDetailMapper.selectByOrderId(id);
    }

    @Override
    public Boolean update(Order order) throws SteduException {
        Order oldOrder = orderMapper.selectById(order.getId());
        System.out.println("********************"+oldOrder.toString());
        if(oldOrder == null){
            throw new SteduException("该订单不存在");
        }
        if (order.getStatus()!=null &&( order.getStatus()>6 || order.getStatus()<0))
        {
            throw new SteduException("非法状态");
        }
        if(order.getStatus()!=null && order.getStatus()==6){
            BigDecimal price = BigDecimal.valueOf(0);
            List<OrderDetail> list = oldOrder.getOrderDetails();
            for (OrderDetail orderDetail : list) {
                price = price.add(orderDetail.getPrice());
                Integer count = orderDetail.getCount();
                Goods goods = goodsMapper.selectById(orderDetail.getGoodsId());
                goods.setCount(goods.getCount()+count);
                goodsMapper.update(goods);
            }
            if (order.getStatus()!= 1){
                User user = userMapper.selectById(oldOrder.getUserId());
                user.setMoney(user.getMoney().add(price));
                userMapper.update(user);
            }
        }
        return orderMapper.updateOrder(order) == 1;
    }

    @Override
    public Order selectById(String id) throws SteduException {
        Order order = orderMapper.selectById(id);
        if(order == null){
            throw new SteduException("该订单不存在");
        }
        return order;
    }

    @Transactional(rollbackFor = SteduException.class)
    @Override
    public void pay(String orderId, Integer userId, String paypwd) throws SteduException {
        Order order = orderMapper.selectById(orderId);
        if(order == null){
            throw new SteduException("订单不存在，无法支付");
        }
        if (order.getStatus() != 0){
            throw new SteduException("订单已支付");
        }if (order.getUserId() != userId){
            throw new SteduException("非法订单");
        }
        BigDecimal sum = new BigDecimal(0);
        for (OrderDetail orderDetail : order.getOrderDetails()){
            sum = sum.add(orderDetail.getPrice().multiply(new BigDecimal(orderDetail.getCount())));
        }
        User user = userMapper.selectById(userId);
        if (user.getMoney().compareTo(sum)<0){
            throw new SteduException("余额不足，无法支付");
        }
        if (user.getPayPassword() == null){
            throw new SteduException("当前用户未设置密码，请先设置密码");
        }
        if (!MD5Util.getMD5(paypwd + user.getSalt()).equals(user.getPayPassword())){
            throw new SteduException("支付密码不正确，请重新支付");
        }

        user.setMoney(user.getMoney().subtract(sum));
        userMapper.update(user);
        order.setStatus(1);
        orderMapper.updateOrder(order);
    }

    @Override
    public List<Order> selectByUserId(Integer userId) {
        return orderMapper.selectByUserId(userId);
    }

    @Override
    public List<OrderChart> selectByStatus() {
        return orderMapper.selectByStatus();
    }
}
